#include "recordingwavaudio.h"
#include <QFile>

#ifdef Q_OS_MAC

    #define FMT_NAME  "avfoundation"
    #define url ":0"
#else

    #define FMT_NAME 'dshow'
    #define url ''
#endif

#define ERRMSG(err_num)  char err_buf[1024];  \
    av_strerror(err_num,err_buf,sizeof (err_buf));

RecordingWAVAudio::RecordingWAVAudio(QObject *parent) : QThread(parent)
{
    init();
}

RecordingWAVAudio::~RecordingWAVAudio()
{

    disconnect();

    requestInterruption();

    quit();

    wait();

    qDebug() << "RecordingWAVAudio destroy";

}

void RecordingWAVAudio::recordingWAV()
{
    this->start();
}

void RecordingWAVAudio::init()
{
    connect(this,&QThread::finished,this,&QThread::deleteLater);
}

void RecordingWAVAudio::run()
{

//   const char * wavPath = "/Users/apple/Documents/ffmpeg/qt/audio/recoding_01.wav";
   const char * wavPath = "/Users/tgy/Documents/ffmpeg/audio/recoding_01.wav";

   AVInputFormat* inputFormat = av_find_input_format(FMT_NAME);

   if (inputFormat == nullptr) {

       qDebug() << "av_find_input_format fail";
       return;
   }

   AVFormatContext* context = nullptr;

   int res = avformat_open_input(&context,url,inputFormat,nullptr);

   if (res != 0) {

        ERRMSG(res);
        qDebug() << err_buf;
        return;
   }

   WAVHead wavHead;



    AVStream* stream = context->streams[0];

    AVCodecParameters* codecParameters = stream->codecpar;
    wavHead.sampleRate = codecParameters->sample_rate;
    wavHead.numChannel = codecParameters->channels;
    enum AVCodecID codecId = codecParameters->codec_id;
    wavHead.bitsPerSample = av_get_bits_per_sample(codecId);

    if (codecId >= AV_CODEC_ID_PCM_F32BE) {

      wavHead.dataType = 3;
    }

    wavHead.init();

    QFile wavFile(wavPath);

    if(!wavFile.open(QFile::WriteOnly)) {

        avformat_close_input(&context);
        qDebug() << wavPath << " open fail";
        return;
    }

    wavFile.write((const char*)&wavHead,sizeof (WAVHead));

    AVPacket* packet = av_packet_alloc();
    int pcmDataAllLen = 0;
    while (!isInterruptionRequested()) {

       res = av_read_frame(context,packet);

       if(res == 0) {

           pcmDataAllLen += packet->size;
           wavFile.write((char *)packet->data,packet->size);
           unsigned long long time = 1000.0 * pcmDataAllLen / wavHead.byteRate;
           emit timeCallBack(time);
       }else if(res == AVERROR(EAGAIN)) {

           continue;
       }else {

           qDebug("av_read_frame fail");
           av_packet_free(&packet);
           wavFile.close();
           avformat_close_input(&context);
           return;
       }

    }


    int riffChunkSize = pcmDataAllLen + sizeof(WAVHead) - 8;

    qDebug() << "riffChunkSize:" << riffChunkSize;
    qDebug() << "pcmDataAllLen:" << pcmDataAllLen;
    wavFile.seek(4);
    wavFile.write((char *)&riffChunkSize,4);
    wavFile.seek(sizeof (WAVHead) - 4);
    wavFile.write((char *)&pcmDataAllLen,4);

    av_packet_free(&packet);
    wavFile.close();
    avformat_close_input(&context);
}




